import yaml
import os.path
from string import maketrans

class LabelUtils2:
    label_to_info = None
    type_parent = None
    clean_table = maketrans(' /','--')

    @staticmethod
    def EnsureLabelsLoaded():
        if LabelUtils2.label_to_info: return
        yaml_path = os.path.join(os.path.dirname(__file__), 'labels.yaml')
        yaml_file = open(yaml_path, 'r')
        raw = yaml.load(yaml_file)
        yaml_file.close()
        LabelUtils2.label_to_info = {}
        LabelUtils2.type_parent = {}
        for raw_type_info in raw:
            label_type = raw_type_info['type-id']
            parent_type = raw_type_info['parent-type-id'] if 'parent-type-id' in raw_type_info else None
            if parent_type:
                LabelUtils2.type_parent[label_type] = parent_type
                label_sets = [(parent, labels) for parent, labels in
                              raw_type_info['labels'].items()]
            else:
                LabelUtils2.type_parent[label_type] = ''
                label_sets = [ ('', raw_type_info['labels']) ]
            for label_set in label_sets:
                label_parent = label_set[0]
                for label_info in label_set[1]:
                    if type(label_info).__name__ == 'list':
                        label_text = label_info[0]
                        label_id = label_info[1]
                    else:
                        label_text = label_info
                        label_id = LabelUtils2.TextToId(label_text.replace(' - ', '-'))
                    full_id = '%s:%s' % (label_type, label_id)
                    LabelUtils2.label_to_info[full_id] = {
                        'type' : label_type,
                        'id' : label_id,
                        'parent' : label_parent,
                        'text' : label_text
                        }

    @staticmethod
    def GetTypes():
        LabelUtils2.EnsureLabelsLoaded()
        return [child for child, parent in type_parent.items()]

    @staticmethod
    def GetTypeLabels(type_id):
        LabelUtils2.EnsureLabelsLoaded()
        if type_id not in LabelUtils2.type_parent: return None
        return [ LabelUtils2.label_to_info[label]['id'] for label in LabelUtils2.label_to_info if LabelUtils2.label_to_info[label]['type'] == type_id ]

    @staticmethod
    def GetLabelParent(child):
        LabelUtils2.EnsureLabelsLoaded()
        if child[0] not in LabelUtils2.type_parent: return None
        full_id = LabelUtils2.LabelToId(child)
        if full_id not in LabelUtils2.label_to_info: return None
        label_info = LabelUtils2.label_to_info[full_id]
        return (LabelUtils2.type_parent[child[0]], label_info['parent'])

    # Note: this must match label-topic-box.js/clean_label()
    @staticmethod
    def TextToId(text):
        return unicode(text.lower().translate(LabelUtils2.clean_table, "')("))

    @staticmethod
    def LabelToId(label):
        return ':'.join(label)
    
    @staticmethod
    def LabelToText(label):
        LabelUtils2.EnsureLabelsLoaded()
        full_id = LabelUtils2.LabelToId(label)
        if full_id not in LabelUtils2.label_to_info: return None
        return LabelUtils2.label_to_info[full_id]['text']

    @staticmethod
    def ExtractLabelsByType(labels, types):
        typed = []
        other = []
        for label in labels:
            if label[1] in types:
                typed.append(label)
            else:
                other.append(label)
        return (typed, other)
